package com.miao.hong.fang.admin;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.upload.FormFile;
import org.apache.struts.validator.DynaValidatorActionForm;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import com.miao.hong.fang.admin.service.AdminService;
import com.miao.hong.fang.course.CourseTO;
import com.miao.hong.fang.course.service.CourseService;
import com.miao.hong.fang.teacher.TeacherTO;
import com.miao.hong.fang.util.SpringBeansHolder;
import com.miao.hong.fang.util.StringUtil;
import com.miao.hong.fang.util.Utils;
import com.miao.hong.fang.util.pagination.ListAndCount;
import com.miao.hong.fang.util.pagination.PaginationContext;

public class AdminAction extends DispatchAction{

	private AdminService adminService = SpringBeansHolder.getInstance().getAdminService();
	private CourseService courseService = SpringBeansHolder.getInstance().getCourseService();
	
	public ActionForward addCourse(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception { 
		
		checkAdminAccess(request);
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;		
		CourseTO courseTO = (CourseTO) dynaForm.get("courseTO");
		
		adminService.addCourse(courseTO);
		
		return mapping.findForward("success");
	}

	public ActionForward searchCourse(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception  {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		String courseTitle = (String) dynaForm.get("courseTitle");
		String coursePeriod = (String) dynaForm.get("coursePeriod");
		String courseStartTimeAsStr = (String) dynaForm.get("courseStartTimeAsStr");
		String courseEndTimeAsStr = (String) dynaForm.get("courseEndTimeAsStr");
		String coursePrice = (String) dynaForm.get("coursePrice");
		String courseCity = (String) dynaForm.get("courseCity");
		String courseCategory = (String) dynaForm.get("courseCategory");
		String courseTeacher = (String) dynaForm.get("courseTeacher");
		String isHotCourse = (String) dynaForm.get("isHotCourse");
		String isRecommendCourse = (String) dynaForm.get("isRecommendCourse");
		String isPublicCourse = (String) dynaForm.get("isPublicCourse");
		
		ListAndCount result = adminService.searchCourse(courseTitle, coursePeriod, courseStartTimeAsStr, courseEndTimeAsStr, 
				coursePrice, courseCity, courseCategory, courseTeacher, isHotCourse, isRecommendCourse, isPublicCourse);
		
		request.setAttribute("courseCategory", courseCategory);
		request.setAttribute("courseTeacher", courseTeacher);
		
		request.setAttribute("courseList", result.getList());
		request.setAttribute("totalCount", String.valueOf(result.getCount()));
		
		request.setAttribute("paginationSortOrderData", PaginationContext.getPaginationSortOrderData());
		
		return mapping.findForward("success");
	} 
	
	public ActionForward viewEditCourse(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String courseId = request.getParameter("courseId");		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		
		//redirect to viewedit from update
		if(StringUtil.isEmpty(courseId)) {
			courseId = ((CourseTO) dynaForm.get("courseTO")).getCourseId();
		}
		
		CourseTO to = adminService.getCourseDetail(courseId);
		dynaForm.set("courseTO", to);	
		request.setAttribute("categoryList", courseService.getAllCourseCategory());
		request.setAttribute("teacherList", adminService.getTeacherByCategory(to.getCourseCategory()));
		
		return mapping.findForward("success");
	}
	
	public ActionForward updateCourse(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;		
		CourseTO courseTO = (CourseTO) dynaForm.get("courseTO");
		
		adminService.updateCourse(courseTO);
		
		return mapping.findForward("success");
	}
	
	public ActionForward deleteCourse(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String courseId = request.getParameter("courseId");
		if(StringUtil.isEmpty(courseId)) {

			DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
			String[] deleteSelection = (String[]) dynaForm.get("deleteSelection");
			
			for(String id:deleteSelection) {
				
				String[] arr = id.split("\\|");
				adminService.deleteCourse(arr[0], arr[1]);
			}
		}else {
			String version = request.getParameter("version");
			adminService.deleteCourse(courseId, version);
		}

		return mapping.findForward("success");
	}
	
	public ActionForward getCourseCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		List<String> list = courseService.getAllCourseCategory();
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(list.toString());
		return null;		
	}
	
	public ActionForward getTeacherByCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
//		String category = request.getParameter("category");
		String category = java.net.URLDecoder.decode(request.getParameter("category"), "UTF-8");
		
		//need to fix
		List list = adminService.getTeacherByCategory(category);		
		
		JSONObject resultJson = new JSONObject();
		JSONArray options = new JSONArray();
		
		TeacherTO to = null;
		for (int i = 0; i < list.size(); i++) {
			to = (TeacherTO) list.get(i);
			
			JSONObject json = new JSONObject();
			json.put("key", to.getTeacherId());
			json.put("value", to.getTeacherName());
			options.add(json);			
		}
		
		resultJson.put("options", options);
		
		response.setCharacterEncoding("utf-8");
		response.setContentType("application/x-json");
		
		response.getWriter().write(resultJson.toString());
		
		return null;
	}
	
	public ActionForward validateTeacherName(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String teacherName = request.getParameter("teacherName");
		response.getWriter().write(String.valueOf(adminService.validateTeacherName(teacherName)));
		
		return null;
	}
	
	public ActionForward addTeacherProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;		
		
		FormFile teacherImage = (FormFile) dynaForm.get("teacherImage");
		String picPath = request.getSession().getServletContext().getRealPath("images/teacher");
		
		saveTeacherImageToPath(teacherImage.getFileData(), picPath + File.separator + teacherImage.getFileName());
		
		TeacherTO teacherTO = (TeacherTO) dynaForm.get("teacherTO");
		teacherTO.setTeacherImageName(teacherImage.getFileName());
		
		String id = adminService.addTeacher(teacherTO);
		saveTeacherImageToDB(id, teacherImage);
		
		//?? 清空页面 ??
		request.removeAttribute(mapping.getAttribute());
		
		return mapping.findForward("success");
	}
	
	public ActionForward searchTeacherProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		
		String teacherName = (String) dynaForm.get("teacherName");
		String teacherDesc = (String) dynaForm.get("teacherDesc");
		String teachMajor = (String) dynaForm.get("teachMajor");
		
		ListAndCount result = adminService.searchTeacher(teacherName, teacherDesc, teachMajor);
		
		//reduce the teacherDesc length
		List teacherList = result.getList();
		
		TeacherTO to = null;		
		for(int i = 0, j = teacherList.size(); i < j; i++) {
			to = (TeacherTO) teacherList.get(i);
			teacherDesc = to.getTeacherDesc();
			
			if(teacherDesc.length() > 32) {
				to.setTeacherDesc(teacherDesc.substring(0, 30));
			}
		}
		
		request.setAttribute("teacherList", result.getList());
		request.setAttribute("totalCount", Integer.valueOf(12));
		
		request.setAttribute("paginationSortOrderData", PaginationContext.getPaginationSortOrderData());
		
		return mapping.findForward("success");
	}

	public ActionForward deleteTeacher(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String teacherId = request.getParameter("teacherId");
		if(StringUtil.isEmpty(teacherId)) {
			DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
			
			String[] deleteSelection = (String[]) dynaForm.get("deleteSelection");
			
			for(String id:deleteSelection) {
				
				String[] arr = id.split("\\|");
				adminService.deleteTeacher(arr[0], arr[1]);
			}
		}else {
			String version = request.getParameter("version");
			adminService.deleteTeacher(teacherId, version);
		}
		
		return mapping.findForward("success");
	}
	
	public ActionForward viewEditTeacher(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;		
		
		String teacherId = request.getParameter("teacherId");
		
		//redirect to viewedit from update
		if(StringUtil.isEmpty(teacherId)) {
			teacherId = ((TeacherTO) dynaForm.get("teacher")).getTeacherId();
		}
		
		TeacherTO to = adminService.getTeacherDetail(teacherId);		
		dynaForm.set("teacher", to);
				
		String teacherImagePath = request.getContextPath() + "/images/teacher/" + to.getTeacherImageName();
		String teacherImageRealPath = request.getSession().getServletContext().getRealPath("images/teacher/" + to.getTeacherImageName());
		File file = new File(teacherImageRealPath);
		if(!file.exists()) {
			BackupFileTO fileTO = adminService.getBackupFile(teacherId);
			saveTeacherImageToPath(fileTO.getFile(), teacherImageRealPath);
		}
		
		request.setAttribute("teacherImagePath", teacherImagePath);
		
		//get the courses under this teacher
		ListAndCount courseList = adminService.getCoursesByTeacher(teacherId);
		request.setAttribute("courseList", courseList);
		request.setAttribute("totalCount", Integer.valueOf(31));		
		request.setAttribute("paginationSortOrderData", PaginationContext.getPaginationSortOrderData());
		
		return mapping.findForward("success");
	}
	
	public ActionForward updateTeacherProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;		
		TeacherTO teacherTO = (TeacherTO) dynaForm.get("teacher");
		
		FormFile teacherImage = (FormFile) dynaForm.get("teacherImage");
		if (StringUtil.isNotEmpty(teacherImage.getFileName())) {
			String picPath = request.getSession().getServletContext().getRealPath("images/teacher");
			saveTeacherImageToPath(teacherImage.getFileData(), picPath + File.separator + teacherImage.getFileName());
			adminService.deleteBackupFile(teacherTO.getTeacherId());
			this.saveTeacherImageToDB(teacherTO.getTeacherId(), teacherImage);
			
			teacherTO.setTeacherImageName(teacherImage.getFileName());
		}
		
		adminService.updateTeacher(teacherTO);
		return mapping.findForward("success");
	}

	public ActionForward manageCourseCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		//get all the course category
		
		List<String> courseCategoryList = courseService.getAllCourseCategory();
		
		request.setAttribute("courseCategoryList", courseCategoryList);
		
		return mapping.findForward("success");
		
	}

	public ActionForward addCourseCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		String courseCategory = (String) dynaForm.get("courseCategory");
		
		adminService.addCourseCategory(courseCategory);
		
		return mapping.findForward("success");
	}
	
	public ActionForward updateCourseCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String oldValue = request.getParameter("oldValue");
		String newValue = request.getParameter("newValue");

		//更新所有 和该 category 关联的 teacher 和 course 记录
		if(!newValue.equals(oldValue)) {
			adminService.updateCourseCategory(oldValue, newValue);	
		}
		
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(newValue);
		return null;
	}
		
	public ActionForward deleteCourseCategory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		String categoryName = request.getParameter("categoryName");
		
		//删除 所有和该 category 关联的 teacher 和 course 记录
		adminService.deleteCourseCategory(categoryName);		
		return null;
	}
	
	public ActionForward addContactInfoProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		String aboutUs = dynaForm.getString("aboutUs");
		String contantPerson = dynaForm.getString("contantPerson");
		String phone = dynaForm.getString("phone");
		String email = dynaForm.getString("email");
		String qq = dynaForm.getString("qq");
		String msn = dynaForm.getString("msn");
		
		adminService.addContactInfo(aboutUs, contantPerson, phone, email, qq, msn);
		return mapping.findForward("success");
	}
	
	public ActionForward getContactInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		ContactInfoTO to = adminService.getContactInfo();
		
		dynaForm.set("contactInfo", to);
		return mapping.findForward("success");
	}
	
	public ActionForward updateContactInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		DynaValidatorActionForm dynaForm = (DynaValidatorActionForm) form;
		ContactInfoTO to = (ContactInfoTO) dynaForm.get("contactInfo");
		adminService.updateContactInfo(to);
		
		Utils.saveMessages(request, "update.success");
		return mapping.findForward("success");
	}
	
	public ActionForward updateIndex(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		checkAdminAccess(request);
		
		List list = adminService.getAllCourse();
		String indexPath = request.getSession().getServletContext().getRealPath("lucene_index");
		File file = new File(indexPath);
		if(!file.exists()) {
			file.mkdir();
		}
		IndexWriter writer = new IndexWriter(FSDirectory.open(file), new StandardAnalyzer(Version.LUCENE_30), 
				true, IndexWriter.MaxFieldLength.LIMITED);
		Document doc = null;
		CourseTO to = null;
		for(int i = 0; i < list.size(); i++) {
			to = (CourseTO) list.get(i);
			doc = new Document();
			doc.add(new Field("id", to.getCourseId(), Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("courseTitle", to.getCourseTitle(), Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("courseMainPoint", to.getCourseMainPoint(), Field.Store.YES, Field.Index.ANALYZED));
			
			doc.add(new Field("courseCity", to.getCourseCity(), Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("courseCategory", to.getCourseCategory(), Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("courseStartTimeAsStr", to.getCourseStartTimeAsStr(), Field.Store.YES, Field.Index.ANALYZED));
			
			doc.add(new Field("titleAndMainPointJoin", to.getCourseTitle()+ " " + to.getCourseMainPoint(), Field.Store.YES, Field.Index.ANALYZED));
			
			writer.addDocument(doc);
		}
		writer.close();
		
		return mapping.findForward("success");
	}
	
	private void saveTeacherImageToPath(byte[] fileData, String filePath) throws IOException {

		OutputStream os = null;
		InputStream is = null;

		try {
			int i = filePath.lastIndexOf(File.separator);
			String dir = filePath.substring(0, i);
			File file = new File(dir);
			if(!file.exists()) {
				file.mkdir();
			}

			File destinationFile = new File(filePath);
			if(!destinationFile.exists()) {
				os = new FileOutputStream(destinationFile);
				is = new ByteArrayInputStream(fileData);		
				byte[] b = new byte[1024];
				int count = is.read(b);
				while(count > -1) {
					os.write(b, 0, count);
					count = is.read(b);
				}
				is.close();
				os.close();
			}
		} catch (IOException ex) {
			
		}finally {
			try {
				if(is != null && os != null) {
					is.close();	
					os.close();
				}
			} catch (IOException e) {		
				throw new IOException(e.getMessage());
			}
		}
	}
	
	public ActionForward displayImage(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		
		List list = adminService.getAllImages();
				
		request.setAttribute("images", list);
		return mapping.findForward("success");
	}
	
	public ActionForward getImage(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
		
		String id = request.getParameter("id");
		byte[] image = adminService.getImage(id);
		
		OutputStream os = response.getOutputStream();
		
		response.setContentType("image/jpeg");
		os.write(image);
		os.close();		
		
		//return mapping.findForward("success");
		return null;
	}
	
	
	private void saveTeacherImageToDB(String id, FormFile file) throws Exception {
		adminService.saveTeacherImageToDB(id, file);
	}
	
	private boolean checkAdminAccess(HttpServletRequest request) throws Exception {
		
		boolean canAccess = false;
		HttpSession session = request.getSession();
		if(session.getAttribute("userId")!=null && session.getAttribute("isAdmin")!=null && "Y".equals(session.getAttribute("isAdmin"))) {
			canAccess = true;
		} else {
			throw new Exception();
		}
		return canAccess;
	}
}
	